/***************************************************************************************
 * object_reflection.cpp
 * 描述：c++ 实现对象的反射机制,参考网络代码，添加注释
 * 作者: xhome
 * 时间:2020/5/20
 ***************************************************************************************/

#include <iostream>
#include <map>
#include <memory>
#include <functional>

using namespace std;

//个人浅解：
//模板函数. 参数为空, 返回值为void * 指针.
//将其当做std::string    、std::vector<> 、这样的类型就可以了。只不过其值为函数指针，但比函数指针更灵活。
//因为std::function  是一种模板，所以要传入类型，就如std::vector<int>  传入类型int一样
//不过,std::function传入的是函数类型  返回值 （参数类型） 如：std::function<void (int)>

#define FUNC  function<void * (void)>

//定义反射类
class Reflector
{
private:
    map<std::string, FUNC> object_map; //保存对象名称, 对象创建函数
    static shared_ptr<Reflector> ptr;

public:
    void * create_object(const string & str)
    {
        for(auto &x: object_map){
            if(x.first == str){
                return x.second();  //函数名()  表示函数的调用.
            }
        }
    }

    //注册对象.
    void register_object(const string & class_name, FUNC && generator)
    {
        object_map[class_name] = generator;
    }

    //创建单例模式
    static shared_ptr<Reflector> instance()
    {
        if(ptr == nullptr){
            ptr.reset(new Reflector());
        }
        return ptr;
    }

};

shared_ptr<Reflector> Reflector::ptr = nullptr;

//对象注册, forward 根据变量推导类型
class RegisterAction{
public:
    RegisterAction(const string & class_name, FUNC && generator){
        Reflector::instance()->register_object(class_name, forward<FUNC>(generator));
    }
};

// c++ 中 单# 号代表的是将字符当成字符串处理, ## 代表的是连接符
// define REGISTER(CLASS_NAME)    RegisterAction g_register_action_##CLASS_NAME(类名称, 匿名函数名称)  定义类构造器

#define REGISTER(CLASS_NAME)\
RegisterAction g_register_action_##CLASS_NAME(#CLASS_NAME, [](){return new CLASS_NAME();})




